
package com.xebest.web.controller.restapi;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.xebest.api.dto.*;
import com.xebest.api.dto.resdto.OrderInfoResDTO;
import com.xebest.api.service.ForErpOrderIApiService;
import com.xebest.common.base.controller.BASEMessage;
import com.xebest.common.base.controller.BaseController;
import com.xebest.common.base.controller.BaseResponse;
import com.xebest.common.base.dto.BaseResponseDTO;
import com.xebest.common.enums.erp.order.VenOrderPayStatusEnum;
import com.xebest.common.enums.erp.order.VenOrderPayTypeEnum;
import com.xebest.common.enums.erp.order.VenOrderStatusEnum;
import com.xebest.common.enums.erp.storehouse.VenStoreTmsStatusEnum;
import com.xebest.common.enums.logtype.ErpLogTypeEnum;
import com.xebest.config.SendGoodOrderSender;
import com.xebest.constant.XeErrorCode;
import com.xebest.util.HttpTookit;
import com.xebest.util.XeVenBusConstans;
import com.xebest.util.msg.XeVenOrderMsg;
import com.xebest.web.model.XeVenExpHandleEntity;
import com.xebest.web.model.XeVenOrderCreditCardRecordsEntity;
import com.xebest.web.model.XeVenOrderInfoEntity;
import com.xebest.web.service.*;
import com.xebest.web.view.ErpUserInfo;
import com.xebest.web.view.XeVenSendView;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.*;

/**
 * 订单同步接口
 *
 * @author 李贝贝
 * @since 2017年6月28日 上午9:51:42
 */
@RestController
@RequestMapping("restapi/order")
public class XeVenOrderRestApi extends BaseController {

    private static Logger log = LoggerFactory.getLogger(XeVenOrderRestApi.class);//日志记录

    @Autowired
    private XeVenOrderSyncOrderService xeVenOrderSyncOrderService;//同步订单业务操作类

    @Autowired
    private XeVenOrderCreditcardRecordsService xeVenOrderCreditcardRecordsService; //pos支付成功回调操作类

    @Autowired
    private XeVenSendGoodsService xeVenSendGoodsService;//发货业务处理

    @Autowired
    private ForErpOrderIApiService forErpOrderIApiService; //发货订单同步业务

    @Autowired
    private XeVenOrderService xeVenOrderService;//订单业务

    @Autowired
    private XeVenExpHandleService xeVenExpHandleService;//异常补偿业务

    @Autowired
    private XeVenPurchService xeVenPurchService;//采购单业务

    /**
     * 鲜易云ERP订单同步接口
     *
     * @author 李贝贝
     * @since 2017年6月28日 上午10:34:15
     */
    @RequestMapping("/saveXeVenOrder")
    public BaseResponseDTO insertXeVenOrder(@RequestBody XeVenOrderSyncDTO iDto) {
        String incomParamJson = "";
        try {
            //1、验证参数
            List<XeVenOrderInfoDTO> orderInfoDTOList = iDto.getErpOrderList();
            incomParamJson = JSONObject.toJSONString(orderInfoDTOList);
            log.info("鲜易云ERP订单同步接口传入参数： {}", incomParamJson);
            List<String> orderList = new ArrayList<String>();
            for (int i = 0; i < orderInfoDTOList.size(); i++) {
                orderList.add(orderInfoDTOList.get(i).getOrderId());
            }
            BigDecimal orderNum = xeVenOrderSyncOrderService.countOrderExists(orderList);//查询订单是否存在
            log.info("鲜易云ERP订单同步接口查询订单是否存在： {}", orderNum);
            if (orderNum.intValue() > 0) {
                log.info("鲜易云ERP订单同步接口查询订单存在： {}", orderNum);
                return sendApiOK(iDto.getSpanId());
            }
            //2、拼装参数
            List<XeVenOrderInfoEntity> orderInfoList = JSONArray.parseArray(incomParamJson, XeVenOrderInfoEntity.class);
            log.info("鲜易云ERP订单同步接口保存实体为参数： {}", JSONObject.toJSONString(orderInfoList));
            //3、返回结果
            int result = xeVenOrderSyncOrderService.insertXeVenOrderBatch(orderInfoList);
            log.info("鲜易云ERP订单同步接口执行结果：{}", result);
        } catch (Exception e) {
            log.error("鲜易云ERP订单同步接口失败：{}", e);
            log.error("鲜易云ERP订单同步接口失败传入参数： {}", incomParamJson);
            return sendApiError(iDto.getSpanId());
        }
        return sendApiOK(iDto.getSpanId());
    }

    /**
     * 前台取消/确认收货订单接口
     *
     * @author ruancz
     * @since 2017年7月6日 下午4:13:50
     */
    @RequestMapping("/updateXeVenOrder")
    public BaseResponseDTO updateXeVenOrderInfo(@RequestBody XeVenOrderInfoDTO iDto) {
        String incomParamJson = JSONObject.toJSONString(iDto);
        log.info("鲜易云ERP订单取消接口传入参数： {}", incomParamJson);
        XeVenOrderInfoEntity orderEntity = JSON.parseObject(incomParamJson, XeVenOrderInfoEntity.class);
        log.info("鲜易云ERP订单取消接口保存实体为：{}", JSONObject.toJSONString(orderEntity));
        try {
            int result = xeVenOrderSyncOrderService.updateXeVenOrderInfo(orderEntity);
            if (result == 0) {
                return sendApiError(iDto.getSpanId());
            }
        } catch (Exception e) {
            log.error("鲜易云ERP订单取消接口失败：{}", e);
            return sendApiError(iDto.getSpanId());
        }
        return sendApiOK(iDto.getSpanId());
    }

    /**
     * 待付款订单支付状态同步接口
     * 商城订单付款，需同步ERP订单为已支付，同时进行分仓库存操作，流转到待审核订单列表或者异常订单列表
     *
     * @author 李贝贝
     * @since 2017年8月16日 上午10:39:49
     */
    @RequestMapping("/paySyncOrderStatus")
    public BaseResponseDTO paySyncOrderStatus(@RequestBody XeVenOrderInfoDTO iDto) {
        String incomParamJson = JSONObject.toJSONString(iDto);
        log.info("待付款订单支付状态同步接口传入参数： {}", incomParamJson);
        try {
            List<String> orderIdList = iDto.getOrderIdList();
            if (null != orderIdList && orderIdList.size() > 0) {
                for (String orderId : orderIdList) {
                    Map<String, Object> params = new HashMap<String, Object>();
                    params.put("orderId", orderId);
                    //查询订单 和 订单明细
                    XeVenOrderInfoEntity orderEntity = xeVenOrderSyncOrderService.getWaitPayOrder(params);
                    if (orderEntity != null) {
                        orderEntity.setPayNumber(iDto.getPayNumber());//支付单号
                        orderEntity.setPayTime(iDto.getPayTime());//支付时间
                        orderEntity.setPayChannel(iDto.getPayChannel());//支付渠道
                        int result = xeVenOrderSyncOrderService.updatePayOrder(orderEntity);
                        log.info("待付款订单支付状态：单号{},执行结果{}", orderId, result);
                    }
                }
            } else {
                return sendApiError(iDto.getSpanId());
            }
        } catch (Exception e) {
            log.error("待付款订单支付状态同步接口失败：{}", e);
            return sendApiError(iDto.getSpanId());
        }
        return sendApiOK(iDto.getSpanId());
    }


    @RequestMapping("/queryRemarks")
    public XeVenOrderInfoResponseDTO queryRemarks(@RequestBody XeVenOrderInfoDTO iDto) {
        String incomParamJson = JSONObject.toJSONString(iDto);
        log.info("订单备注同步接口传入参数： {}", incomParamJson);
        XeVenOrderInfoResponseDTO orderInfoResponse = new XeVenOrderInfoResponseDTO();
        try {
            Map<String, Object> params = new HashMap<String, Object>();
            params.put("orderId", iDto.getOrderId());
            //查询订单 和 订单明细
            XeVenOrderInfoEntity orderEntity = xeVenOrderSyncOrderService.queryRemarks(params);
            if (null != orderEntity) {
                orderInfoResponse.setOrderId(orderEntity.getOrderId());
                orderInfoResponse.setOrderStatus(orderEntity.getOrderStatus());
                orderInfoResponse.setSystemRemark(orderEntity.getSystemRemark());
                orderInfoResponse.setOrderRemark(orderEntity.getOrderMark());
                orderInfoResponse.setLockRemark(orderEntity.getLockRemark());
                orderInfoResponse.setCancelRemark(orderEntity.getCancelRemark());
                orderInfoResponse.setVendorRemark(orderEntity.getVendorRemark());
                orderInfoResponse.setOrderMark(orderEntity.getOrderMark());
                orderInfoResponse.setPromotOrderType(orderEntity.getPromotOrderType());
            }
            log.info("=========" + JSONObject.toJSONString(orderInfoResponse) + "--------");
        } catch (Exception e) {
            log.error("订单备注同步接口失败：{}", e);
            return sendApiError(iDto.getSpanId(), orderInfoResponse);
        }
        return orderInfoResponse;
    }

    /**
     * pos支付成功同步接口 提供给商城调用
     *
     * @author chenjing
     * @since 16:21 2017/8/28
     */
    @RequestMapping("/posSyncOrderStatus")
    public BaseResponseDTO posSyncOrderStatus(@RequestBody XeVenOrderCreditCardRecordsDto iDto) {
        String incomParamJson = JSONObject.toJSONString(iDto);
        log.info("pos支付成功同步接口传入参数： {}", incomParamJson);
        String orderId = iDto.getOrderId();
        if (StringUtils.isBlank(orderId)) {
            return sendApiError("订单号不能为空！", iDto.getSpanId());
        }
        //验证订单状态
        XeVenOrderInfoEntity entity = xeVenOrderCreditcardRecordsService.queryOrderInfo(orderId);
        //如果订单状态为已支付，直接返回
        if (VenOrderPayStatusEnum.ALL_PAID.getValue().equals(entity.getPayStatus())) {
            return sendApiError("重复提交，订单已支付！", iDto.getSpanId());
        }
        //如果订单状态不为待发货或已发货，直接返回
        if (!VenOrderStatusEnum.SEND.getValue().equals(entity.getOrderStatus())
                && !VenOrderStatusEnum.WAIT_SEND.getValue().equals(entity.getOrderStatus())) {
            return sendApiError("订单状态错误！当前订单状态为" + entity.getOrderStatus(), iDto.getSpanId());
        }
        try {
            XeVenOrderCreditCardRecordsEntity recordsEntity = JSON.parseObject(JSON.toJSONString(iDto), XeVenOrderCreditCardRecordsEntity.class);
            recordsEntity.setUserCode(entity.getUserCode());
            int flag = xeVenOrderCreditcardRecordsService.insertRecords(recordsEntity, entity);
            if (flag > 0) return sendApiOK(iDto.getSpanId());
            else return sendApiError(iDto.getSpanId());
        } catch (Exception e) {
            log.error("pos支付同步接口失败：{}", e);
            return sendApiError(iDto.getSpanId());
        }


    }

    /**
     * 鲜易云ERP单个或者多个订单发货
     *
     * @author 李贝贝
     * @since 2017年7月1日 下午4:01:34
     */
    @RequestMapping("send")
    public @ResponseBody
    BaseResponse batchSend(HttpServletRequest request) {
        //1、验证参数
        String orderId = request.getParameter("orderId");
        String merId = request.getParameter("merId");
        String merKey = request.getParameter("merKey");
        String nonceStr = request.getParameter("nonceStr");
        String sign = request.getParameter("sign");
        log.info("供应链订单发货入参：orderId {},merId {},merKey {},nonceStr {},sign {}", orderId, merId, merKey, nonceStr, sign);
        if (StringUtils.isEmpty(orderId) || StringUtils.isEmpty(merId) || StringUtils.isEmpty(merKey) ||
                StringUtils.isEmpty(nonceStr) || StringUtils.isEmpty(sign)) {
            return sendAjaxError(BASEMessage.PARAM_ERROR);
        }
        String signStr = HttpTookit.getSignStr(orderId, nonceStr);//获取加密串
        log.info("本地加密串返回值：orderId {},nonceStr {},signStr {}", orderId, nonceStr, signStr);
        if (!signStr.equals(sign)) {
            return sendAjaxError("加密串错误！");
        }
        //2、获取前台需要传入订单号
        List<String> orderIds = new ArrayList<String>();//待发货订单容器
        orderIds.add(orderId);//订单号
        log.info("订单发货入参：{}", orderIds);
        //3、获取用户登录信息
        Map<String, Object> paramMap = new HashMap<String, Object>();
        paramMap.put("orderIds", orderIds);//待发货订单号
        //4、批量查询要处理的待发货订单
        List<XeVenSendView> waitSendList = xeVenSendGoodsService.queryWaitSendList(paramMap);
        log.info("批量查询要处理的待发货订单:{}", JSONObject.toJSONString(waitSendList));
        Map<String, Object> map = new HashMap<String, Object>();
        map.put(XeVenBusConstans.CODE, XeVenBusConstans.BUSSINESS_SUCCESS);
        String failOrder = "";//发货失败订单号
        String illegalOrder = "";//非法状态订单号
        String resultMsg = "";//发货返回提示信息
        int sendSize = 0;
        List<XeVenSendView> waitUpList = new ArrayList<XeVenSendView>();
        //5、开始执行批量发货操作
        for (int i = 0; i < waitSendList.size(); i++) {
            XeVenSendView sendView = waitSendList.get(i);
            //判断发货状态是否为待发货 是否已经接入TMS
            if (VenStoreTmsStatusEnum.YES.getValue() != sendView.getTmsStatus()) {
                //记录出执行失败订单号
                return sendAjaxError("该订单" + sendView.getOrderId() + "未接入TMS！");
            }
            if (VenOrderStatusEnum.WAIT_SEND.getValue() != sendView.getOrderStatus()) {
                //记录出执行失败订单号
                illegalOrder += " " + sendView.getOrderId();
                return sendAjaxError("该订单" + sendView.getOrderId() + "状态错误！");
            }
            sendView.setSendTime(new Date());
            try {
                int sendResult = xeVenSendGoodsService.updateSend(sendView);//更新发货
                if (sendResult > 0) {
                    waitUpList.add(sendView);//添加待更新发货(商城订单使用)
                    //添加日志
                    ErpUserInfo userInfo = new ErpUserInfo();
                    userInfo.setUserCode(sendView.getUserCode());
                    userInfo.setUserName("tms");
                    xeVenOrderService.insertMqLog(ErpLogTypeEnum.erpOrderModifySend.getValue(), sendView.getOrderId(), "对订单【" + sendView.getOrderId() + "】进行发货操作", userInfo, getRequestIP(), "TMS发货");
                }
                sendSize += sendResult;
            } catch (Exception e) {
                failOrder += " " + sendView.getOrderId();
                log.error("订单发货错误信息:订单号{},发货执行异常{}!", sendView.getOrderId(), e);
            }
        }
        //6、批量发货提示信息拼接
        if (!illegalOrder.equals("")) {
            illegalOrder += XeVenOrderMsg.SEND_ILLEGALMSG;
            resultMsg = " 失败原因：订单号" + illegalOrder;
        }
        if (!failOrder.equals("")) {
            failOrder += XeVenOrderMsg.SEND_FAIL_MSG;
            resultMsg = " 订单号" + failOrder;
        }
        map.put(XeVenBusConstans.MSG, "成功发货" + sendSize + "条！" + resultMsg);
        //7、通知商城订单库已发货，同时算三方商户佣金
        int waitUpListSize = waitUpList.size();//需要通知的订单数量
        List<String> expOrderList = new ArrayList<String>();//如果发货通知异常使用
        try {
            if (waitUpListSize > 0) {
                List<OrderInfoDTO> listDTO = new ArrayList<OrderInfoDTO>();
                OrderInfoDTO paramDTO = new OrderInfoDTO();//商城同步参数
                for (XeVenSendView viewDTO : waitUpList) {
                    expOrderList.add(viewDTO.getOrderId());
                    OrderInfoDTO orderInfoDTO = new OrderInfoDTO();
                    orderInfoDTO.setVenType(viewDTO.getVenType());
                    orderInfoDTO.setOrderId(viewDTO.getOrderId());
                    orderInfoDTO.setSendTime(viewDTO.getSendTime());
                    orderInfoDTO.setOrderStatus(VenOrderStatusEnum.SEND.getValue());
                    orderInfoDTO.setUserCode(viewDTO.getUserCode());
                    orderInfoDTO.setOrderDetailList(JSON.parseArray(JSON.toJSONString(viewDTO.getOrderDetailList()), OrderInfoDetailDTO.class));
                    orderInfoDTO.setPayAmount(viewDTO.getEpayReceAmt() == null ? viewDTO.getPayAmount() : viewDTO.getEpayReceAmt());//应收金额
                    orderInfoDTO.setRealRefundedAmount(viewDTO.getDifferAmount());//退款总额
                    int i = 0;
                    for (OrderInfoDetailDTO detailDTO : orderInfoDTO.getOrderDetailList()) {
                        BigDecimal refundAmount = viewDTO.getOrderDetailList().get(i).getDifferenceAmount();
                        if (refundAmount != null) {
                            // detailDTO.setProPayAmount(detailDTO.getProPayAmount().subtract(refundAmount));//发货金额 = 成交金额-差异退款金额 不算运费
                            detailDTO.setRealRefundedAmount(refundAmount);//退款金额
                        } else {
                            detailDTO.setRealRefundedAmount(new BigDecimal("0.00"));//退款金额
                        }
                        i++;
                    }
                    listDTO.add(orderInfoDTO);
                }
                paramDTO.setOrderInfoList(listDTO);
                log.info("发货通知前台入参 :{}", JSON.toJSONString(paramDTO));
                OrderInfoResDTO orderInfoResDTO = this.forErpOrderIApiService.erpConfirmOrder(paramDTO);
                log.info("发货通知前台出参 :{}", JSON.toJSONString(orderInfoResDTO));
                if (!orderInfoResDTO.getStatus().equals("2000")) {
                    XeVenExpHandleEntity entity = new XeVenExpHandleEntity();
                    entity.setExpType(2);
                    entity.setOrderJson(JSONObject.toJSONString(expOrderList));
                    entity.setExpMsg("TMS正常发货通知异常：" + orderInfoResDTO.getMsg());
                    xeVenExpHandleService.insertXeVenExpHandle(entity);
                }
            }
        } catch (Exception e) {
            try {
                XeVenExpHandleEntity entity = new XeVenExpHandleEntity();
                entity.setExpType(2);
                entity.setOrderJson(JSONObject.toJSONString(expOrderList));
                entity.setExpMsg("接入供应链通知异常：" + e.getMessage());
                xeVenExpHandleService.insertXeVenExpHandle(entity);
            } catch (Exception e1) {
                log.error("发货通知补偿业务执行异常{}!", e1);
            }
            log.error("订单发货通知前台错误信息:同步发货执行异常{}!", e);
        }
        //发送短信通知
        if (waitUpListSize > 0) {
            SendGoodOrderSender.sender.sendMessage(JSONObject.toJSONString(waitUpList));//消息通知
            log.info("发货通知消息成功!");
        }
        //8、返回结果
        return sendAjaxOK(map);
    }

    /**
     * 鲜易消消乐取消订单
     *
     * @author RCZ
     */
    @RequestMapping("cancelOrder")
    public @ResponseBody
    BaseResponseDTO cancelOrder(@RequestBody XeVenOrderInfoDTO dto) {

        log.info("鲜易消消乐取消订单入参: {}", JSON.toJSONString(dto));
        try {
            List<XeVenOrderInfoEntity> orderInfoEntity = this.xeVenOrderService.queryOrderStatusByOrderId(dto.getOrderId());
            if (null == orderInfoEntity || orderInfoEntity.size() == 0) {
                return sendApiError("该订单已删除!", dto.getSpanId());
            }
            if (orderInfoEntity.get(0).getOrderStatus().equals(VenOrderStatusEnum.CANCEL.getValue())) {
                return sendApiError("订单状态已变更,无法取消!", dto.getSpanId());
            }
            orderInfoEntity.get(0).setCancelUser(dto.getSalesmanName());
            if (orderInfoEntity.get(0).getPayType().equals(VenOrderPayTypeEnum.ONLINE_PAY.getValue()) && orderInfoEntity.get(0).getPayStatus().equals(VenOrderPayStatusEnum.UNPAID.getValue())) {
                int result = this.xeVenOrderService.cancelOrderByorderId(orderInfoEntity.get(0), getRequestIP());
                if (result == 1) {
                    return sendApiOK("取消成功", dto.getSpanId());
                } else {
                    return sendApiError("取消失败,请稍后重试", dto.getSpanId());
                }
            } else {
                return sendApiError("只能取消在线支付未支付订单!", dto.getSpanId());
            }
        } catch (Exception e) {
            log.info("鲜易消消乐取消订单异常: {}", e);
            return sendApiError(dto.getSpanId());
        }
    }

    /**
     * 货到付款订单完成支付时，需要更新订单支付状态为已支付
     *
     * @author 李贝贝
     * @since 2018年5月10日 下午6:56:46
     */
    @RequestMapping("/codSyncOrderStatus")
    public BaseResponseDTO podSyncOrderStatus(@RequestBody XeVenOrderInfoDTO iDto) {
        String incomParamJson = JSONObject.toJSONString(iDto);
        log.info("货到付款更新为已支付接口传入参数： {}", incomParamJson);
        try {
            XeVenOrderInfoEntity orderEntity = new XeVenOrderInfoEntity();
            orderEntity.setOrderId(iDto.getOrderId());
            orderEntity.setPayNumber(iDto.getPayNumber());//支付单号
            orderEntity.setPayTime(iDto.getPayTime());//支付时间
            orderEntity.setPayChannel(iDto.getPayChannel());//支付渠道
            orderEntity.setPayStatus(VenOrderPayStatusEnum.ALL_PAID.getValue());//更新为已支付
            int result = xeVenOrderSyncOrderService.podSyncOrderStatus(orderEntity);
            log.info("货到付款更新为已支付接口：单号{},执行结果{}", iDto.getOrderId(), result);
        } catch (Exception e) {
            log.error("货到付款更新为已支付接口失败：{}", e);
            return sendApiError(iDto.getSpanId());
        }
        return sendApiOK(iDto.getSpanId());
    }

    /**
     * 查询商品spu 在订单和采购订单中是否被占用
     *
     * @param spu 商品spu
     * @author zhouys
     */
    @GetMapping("/getSpuTakeUpStatus/{spu}")
    public SpuTakeUpDTO getSpuTakeUpStatus(@PathVariable("spu") String spu) {
        SpuTakeUpDTO dto=new SpuTakeUpDTO();
        dto.setMsg("查询spu是否被占用");
        dto.setStatus(XeErrorCode.PORJECT_SUCCESS);

        int orderCnt = xeVenOrderService.spuTakeUpCount(spu);
        dto.setOrderCnt(orderCnt);
        int purchCnt = xeVenPurchService.spuTakeUpCount(spu);
        dto.setPurchOrderCnt(purchCnt);
        return dto;
    }

}
  
